﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 生成62位进制字符串，并支持混淆，用于生成邀请码等作用
/// </summary>
public class ConverNumber
{
    private static String keys = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//编码,可加一些字符也可以实现72,96等任意进制转换，但是有符号数据不直观，会影响阅读。
    private static int exponent = keys.Length;//幂数

    /// <summary>
    /// decimal value type to 62 string
    /// </summary>
    /// <param name="value">The max value can not more decimal.MaxValue<</param>
    /// <returns>Return a specified 62 encode string</returns>
    public static string ConverNumber2Str(decimal value)//17223472558080896352ul
    {
        string result = string.Empty;
        do
        {
            decimal index = value % exponent;
            result = keys[(int)index] + result;
            value = (value - index) / exponent;
        }
        while (value > 0);

        return result;
    }


    /// <summary>
    /// 62 encode string to decimal
    /// </summary>
    /// <param name="value">62 encode string</param>
    /// <returns>Return a specified decimal number that decode by 62 string</returns>
    public static decimal StrConver2Number(String value)//bUI6zOLZTrj
    {
        decimal result = 0;
        for (int i = 0; i < value.Length; i++)
        {
            int x = value.Length - i - 1;
            result += keys.IndexOf(value[i]) * Pow(exponent, x);// Math.Pow(exponent, x);
        }
        return result;
    }

    /// <summary>
    /// 一个数据的N次方
    /// </summary>
    /// <param name="x"></param>
    /// <returns></returns>
    private static decimal Pow(decimal baseNo, decimal x)
    {
        decimal value = 1;////1 will be the result for any number's power 0.任何数的0次方，结果都等于1
        while (x > 0)
        {
            value = value * baseNo;
            x--;
        }
        return value;
    }

    /// <summary>
    /// 混淆生成指定位数的字符串
    /// </summary>
    /// <param name="value">62进制字符串</param>
    /// <param name="hopeBitNum">希望生成几位字符（当value的位数小于hopeBitNum时才起作用）</param>
    /// <param name="mixNum">加入的混淆数字</param>
    /// <returns></returns>
    public static String MixNumberString(String value, int hopeBitNum, int mixNum)
    {
        int tempNum = hopeBitNum - value.Length;
        for (int i = 0; i < tempNum; i++)
        {
            value = keys[0] + value;
        }
        List<char> charList = new List<char>(value);
        for (int i = 0; i < value.Length; i++)
        {
            int index = keys.IndexOf(value[i]) + (i+1) * mixNum;
            index = index % (keys.Length);
            if (index < 0)
                index = keys.Length + index;
            charList[i] = keys[index];
        }

        StringBuilder bulder = new StringBuilder();
        foreach (var item in charList)
        {
            bulder.Append(item);
        }

        return bulder.ToString();
    }
    /// <summary>
    /// 把混淆字符串还原成62进制字符
    /// </summary>
    /// <param name="mixString">混淆的字符串</param>
    /// <param name="mixNum">加入的混淆数字</param>
    /// <returns></returns>
    public static String RestoreNumberString(String mixString,int mixNum)
    {
        List<char> charList = new List<char>(mixString);
        for (int i = 0; i < mixString.Length; i++)
        {
            int index = keys.IndexOf(mixString[i]) - (i+1) * mixNum;
            index = index % keys.Length;
            if (index < 0)
                index = keys.Length + index;

            charList[i] = keys[index];
        }

        StringBuilder bulder = new StringBuilder();
        foreach (var item in charList)
        {
            bulder.Append(item);
        }

        return bulder.ToString();
    }
}

